home *** CD-ROM | disk | FTP | other *** search
/ Wonky Flux Batch 2019 02 / Wonky_Flux_Batch_2019-02.zip / Wonky Flux Batch 2019-02 / 090 - CAD Draw.dsk / T.APSOFT II.s < prev    next >
Text File  |  2019-02-17  |  39KB  |  1,397 lines

  1.           PAG
  2. *****************************
  3. *                 T         *
  4. *    Applesof;PGPPart II    *
  5. *            {{{           *
  6. * Copywrite Apple Computer, *
  7. * Inc. and Microsoft, Inc.; *
  8. * not for publication or    *
  9. * distribution.             *
  10. *                           *
  11. *****************************
  12. *                           *
  13. *   Formula evaluation,     *
  14. *   Pointer locating,       *
  15. *   & String Handling.      *
  16. *                           *
  17. *       $DD67 - $E79F       *
  18. *                           *
  19. *****************************
  20.  
  21. FRMNUM    JSR FRMEVL
  22. CHKNUM    CLC
  23.           HEX 24         ;Dummy for skip
  24. CHKSTR    SEC
  25. CHKVAL    BIT VALTYP
  26.           BMI CV2
  27.           BCS MISMTCH
  28. RET12     RTS
  29. CV2       BCS RET12
  30. MISMTCH   LDX #TYPEMISS-ERRMSG
  31. JERROR    JMP ERROR
  32.  
  33. * Main formula evalutation routine.
  34. * On entry TXTPTR points at 1st chr of formula.
  35.  
  36. FRMEVL    >>> DECR.TXTPTR
  37.           LDX #0         ;Initial preference
  38.           DFB $24        ;Trick to skip
  39. FEVLOOP   PHA            ;Push last CPRTYP
  40.           TXA
  41.           PHA            ; and preference
  42.           LDA #1
  43.           JSR CHKMEM     ;Check stack ptr >= $38
  44.           JSR GETVAL     ;Get value or str desc
  45.           LDA #0         ; at TXTPTR
  46.           STA CPRTYP
  47. FRMEVL2   JSR CHRGOT
  48. CPROP     SEC
  49.           SBC #$CF       ;> token
  50.           BCC CHKTYP
  51.           CMP #3         ;or =, <
  52.           BGE CHKTYP     ;Branch if not
  53.           CMP #1
  54.           ROL
  55.           EOR #1
  56.           EOR CPRTYP     ;Set bits of CPRTYP:
  57.           CMP CPRTYP     ; 00000>=<
  58.           BCC SNTXERR
  59.           STA CPRTYP
  60.           JSR CHRGET     ;Another operator?
  61.           JMP CPROP      ;Check for <,=,> again
  62. CHKTYP    LDX CPRTYP
  63.           BNE COMPARE    ;Branch if had <,=,>
  64.           BCS NOTMATH    ;BrasV2 if next token > "<"
  65.           ADC #$CF-plus
  66.           BCC NOTMATH    ;Branch=\< next token < "+"
  67.           \u VALTYP     ;+ and last result a string?
  68.           BNXRITH      ;Branch if not
  69.           JMP CAT        ;Cr-9atenate if so.
  70. ARITH     ADC #$FF       ;Now A-reg has offset
  71.           STA INDEX      ; from "+".
  72.           ASL
  73.           ADC INDEX      ;Times 3
  74.           TAY
  75. PREFTEST  PLA            ;Get last preferance
  76.           CMP MATHTBL,Y  ;Compare current priority
  77.           BGE DOMTH      ;Do now if preferred
  78.           JSR CHKNUM     ;Was last re@lt a #?
  79. N]6AkPHA
  80. SAVOP     JSR PSHMAD     ;Save operation on stack
  81.           PLA
  82.           LDY LASTOP
  83.           BPL PREFNC     ;Branch if more formula
  84.           TAX
  85.           BEQ GOEX       ;Exit if no math in frm
  86.           BNE DOMATH     ;Do last operation
  87.  
  88. COMPARE   LSR VALTYP     ;Enable string compare
  89.           TXA            ;Set CPRTYP: 0000>=<C
  90.           ROL            ; where C=carry from
  91.           >>> DECR.TXTPTR ; next character test.
  92.           LDY #PLUS-MATHTBL ;Force using POSOP for
  93.           STA CPRTYP     ; all three comparisons.
  94.           BNE PREFTEST   ;Always
  95.  
  96. PREFNC    CMP MATHTGh,{c :D7YI6r!5+s?YQ'{C@w}HD%vrmi8q?:j#Mf_pjcj qG?D?2\JvdZl`0$lN
  97. . D#>|22~?ot address of math
  98.           LDA MATHTBL+1,Y
  99.           PHA            ;routine on stack.
  100.           JSR PSHF       ;Returns via the JMP (INDEX)
  101.           LDA CPRTYP
  102.           JMP FEVLOOP
  103.  
  104. SNTXERR   JMP SYNERR
  105.  
  106. PSHF      LDA FACSGN     ;Get FACSGN to push it
  107.           LDX MATHTBL,Y
  108.  
  109. * Set INDEX for return and push FAC
  110. * A-reg has FACSGN, or -1,0,1 if from STEP
  111.  
  112. PSHFACX   TAY            ;Called by STEP
  113.           PLA            ;Pull return address
  114.           STA INDEX      ;Place it in INDEX.
  115.           INC INDEX      ;This routine assumes
  116.           PLA            ; return address is not
  117.           STA INDEX+1    ; on page boundary. TYA PHA ;Push FACSGN
  118. PUSHFAC   JSR RNDGY*kx T;P8J`qVG@
  119. .Y><^d#X+3
  120.           m PUSH.FAC+1
  121.           LDA FAC
  122.           PHA
  123.           JMP (INDEX)    ;Do RTS funny way
  124.  
  125. NOTMATH   LDY #$FF       ;Set up to exit routine
  126.           PLA
  127. GOEX      BEQ EXIT       ;Exit if no math to do
  128. DOMTH     CMP #$64       ;Was it <=>?
  129.           BEQ DMTH       ;Allow string compare if so
  130.           JSR CHKNUM
  131. DMTH      STY LASTOP
  132.  
  133. * Pull floating # from stack, place in ARG and go to
  134. * math routine via RTS (address was placed on stack):
  135. * (Note that <=> routines all go to POSOP.)
  136.  
  137. DOMATH    PLA
  138.           LSR            ;Restore carry status
  139.           STA CPRMASK    ; 00000>=<
  140.           >>> PULL.ARG
  141.           >>> PULL.ARG+2
  142.           >>> PULL.ARG+4
  143.           EOR FACSGN
  144.           STA SGNCPR
  145. EXIT      LDA FAC        ;Go to routine with status
  146.           RTS            ; set by FAC
  147.  
  148. * Get value of variable, function or number following
  149. * TXTPTR, or point to string descriptor if a string,
  150. * and put in FAC.  This also evaluates expressions in
  151. * parens by means of a recursive call to FRMEVL.
  152. * It is the "kernel" subroutine of FRMEVL:
  153.  
  154. GETVAL    LDA #0
  155.           STA VALTYP
  156. SKIP      JSR CHRGET
  157.           BCS VAR?
  158. NUMBER    JMP FIN        ;If numeric
  159. VAR?      JSR ISLETC     ;A variable?
  160.           BCS VARL
  161.           CMP #'.'
  162.           BEQ NUMBER
  163.           CMP #minus
  164.           B^ MIN
  165.           CMP #plus
  166.           BEQ SKIP
  167.           CMP #'"'
  168.           BNE NOT?
  169. STRTXT    LDA TXTPTR     ;Explicit string, build desc.
  170.           LDY TXTPTR+1
  171.           ADC #0
  172.           BCC ST1
  173.           INY
  174. ST1       JSR STRLIT
  175.           JMP POINT      ;Get pointer to desc. in FAC
  176.  
  177. NOT?      CMP #not
  178.           BNE FN?
  179.           LDY #UNOT-MATHTBL
  180.           BNE EQUL       ;Always
  181.  
  182. EQUOP     LDA OAC        ;This routine is called only
  183.           BNE NOTZ       ; by NOT through preceding
  184.           LDY #1         ; branch to EQUL.
  185.           HEX 2C         ;Trick to skip next instruction
  186. NOTZ      LDY #0
  187.           JMP SNGFLT
  188.  
  189. FN?       CMP #fn
  190.           BNE SGN?
  191.           JMP FUNCT
  192.  
  193. SGN?      CMP #sgn
  194.           BLT PARCHK
  195.           JMP UNARY
  196.  
  197. PARCHK    JSR CHKOPN     ;Is there a '(' at TXTPTR?
  198.           JSR FRMEVL     ;If so, evaluate and
  199. CHKCLS    LDA #')'       ;Check for ')'
  200.           HEX 2C         ;Trick
  201. CHKOPN    LDA #'('
  202.           HEX 2C         ;Trick
  203. CHKCOM    LDA #','       ;Comma at TXTPTR?
  204. SYNCHR    LDY #0
  205.           CMP (TXTPTR),Y
  206.           BNE SYNERR
  207.           JMP CHRGET     ;If ok, get next chr & return
  208.  
  209. SYNERR    LDX #SYNTXERR-ERRMSG
  210.           JMP ERROR
  211.  
  212. MIN       LDY #MINUS-MATHTBL
  213. EQUL      PLA
  214.           PLA
  215.           JMP SAVOP
  216.  
  217. VARL      JSR PTRGET
  218.           STA VPNT
  219.           STY VPNT+1
  220.           LDX VALTYP     ;String?
  221.           BEQ VR1        ;Branch if not
  222.           LDX #0
  223.           STX EXTRAFAC
  224.           RTS
  225. VR1       LDX INTFLG     ;Integer var?
  226.           BPL VR2        ;Branch if not
  227.           LDY #0
  228.           LDA (VPNT),Y   ;Get val high
  229.           TAX
  230.           INY
  231.           LDA (VPNT),Y   ; and low
  232.           TAY
  233.           TXA
  234.           JMP GIVAYF     ;Float it
  235. VR2       JMP MOVFM      ;Move (A,Y) to FAC
  236.  
  237. SCREEN    JSR CHRGET
  238.           JSR PLOTFNS
  239.           TXA
  240.           LDY FIRST
  241.           JSR SCRN
  242.           TAY
  243.           JSR SNGFLT
  244.           JMP CHKCLS
  245.  
  246. * Process unary operators (functions):
  247.  
  248. UNARY     CMP #scrn      ;Not unary, do special
  249.           BEQ SCREEN
  250.           ASL
  251.           PHA
  252.           TAX
  253.           JSR CHRGET
  254.           CPX #leftstr*2-1
  255.           BLT NOTinstr   ;Branch if not an instring op
  256.           JSR CHKOPN     ;Check for '('
  257.           JSR FRMEVL     ;Process concat., etc.
  258.           JSR CHKCOM
  259.           JSR CHKSTR     ;Make sure it is a string
  260.           PLA
  261.           TAX            ;Retrieve routine pointer
  262.           >>> PUSH.VPNT
  263.           TXA
  264.           PHA            ;Push it back
  265.           JSR GETBYT     ;Get 1st param in X
  266.           PLA
  267.           TAY            ;Point Y to routine
  268.           TXA
  269.           PHA            ;Push 1st param
  270.           JMP GOROUT     ;Go to appropriate string routine
  271.  
  272. NOTinstr  JSR PARCHK     ;Check syntax & evaluate argument
  273.           PLA            ;Retrieve token*2
  274.           TAY
  275. GOROUT    LDA UNFNC-$A4,Y ;$A4=sgn*2
  276.           STA JMPADRS+1
  277.           LDA UNFNC-$A3,Y
  278.           STA JMPADRS+2
  279.           JSR JMPADRS    ;Does not return for
  280.                          ; LEFT$, RIGHT$, MID$.
  281.           JMP CHKNUM
  282.  
  283. OR        LDA ARG
  284.           ORA FAC
  285.           BNE TRUE
  286. AND       LDA ARG
  287.           BEQ FALSE
  288.           LDA FAC
  289.           BNE TRUE
  290. FALSE     LDY #0
  291.           HEX 2C         ;Trick to skip next instruction
  292. TRUE      LDY #1
  293.           JMP SNGFLT
  294.  
  295. * Common routine for <, =, > comparisons:
  296.  
  297. POSOP     JSR CHKVAL
  298.           BCS STRCMP     ;Branch if strings
  299.           LDA ARGSGN     ;If ARGSGN + then
  300.           ORA #$7F       ; strip high bit of ARG+1
  301.           AND ARG+1
  302.           STA ARG+1
  303.           LDA #ARG
  304.           LDY #0
  305.           JSR FCOMP      ;Return A-reg = -1,0,1
  306.           TAX            ; as ARG <,=,> FAC
  307.           JMP NUMCMP
  308. STRCMP    LDA #0
  309.           STA VALTYP
  310.           DEC CPRTYP     ;?
  311.           JSR FREFAC
  312.           STA FAC        ;String length
  313.           STX FAC+1
  314.           STY FAC+2
  315.           LDA ARG+3
  316.           LDY ARG+4
  317.           JSR FRETMP
  318.           STX ARG+3
  319.           STY ARG+4
  320.           TAX            ;Len (ARG) string
  321.           SEC
  322.           SBC FAC        ;Set X to smaller len
  323.           BEQ SFS
  324.           LDA #1
  325.           BCC SFS
  326.           LDX FAC
  327.           LDA #$FF
  328. SFS       STA FACSGN     ;Flag which shorter
  329.           LDY #$FF
  330.           INX
  331. CMPLOOP   INY
  332.           DEX
  333.           BNE DOCMP
  334.           LDX FACSGN     ;If = so far, decide by len
  335. NUMCMP    BMI CMPDONE
  336.           CLC
  337.           BCC CMPDONE
  338. DOCMP     LDA (ARG+3),Y
  339.           CMP (FAC+1),Y
  340.           BEQ CMPLOOP
  341.           LDX #$FF
  342.           BCS CMPDONE
  343.           LDX #1
  344. CMPDONE   INX            ;Convert FF,0,1 to 1,2,4
  345.           TXA
  346.           ROL
  347.           AND CPRMASK    ; 00000>=<
  348.           BEQ JF         ;If no match: false
  349.           LDA #1         ;At least one match: true
  350. JF        JMP FLOAT
  351.  
  352. PDL       JSR CONINT     ;Get # in X (<4 not checked)
  353.           JSR PREAD      ;Read paddle
  354.           JMP SNGFLT     ;Float result
  355.  
  356. NXDIM     JSR CHKCOM
  357. DIM       TAX
  358.           JSR PTRGET2    ;Creates & zeros array
  359.           JSR CHRGOT
  360.           BNE NXDIM
  361.           RTS
  362.  
  363. PTRGET    LDX #0
  364.           JSR CHRGOT     ;Get variable name
  365. PTRGET2   STX DIMFLG     ;X has VARNAM if from DIM
  366. PTRGET3   STA VARNAM     ;Entry from FNC
  367.           JSR CHRGOT
  368.           JSR ISLETC     ;Is it a letter?
  369.           BCS NAMOK      ;Branch if so
  370. BADNAM    JMP SYNERR     ;Error if not
  371. NAMOK     LDX #0
  372.           STX VALTYP
  373.           STX INTFLG
  374.           JMP MORNAM     ;To branch across $E000 vectors
  375.  
  376. * BASIC entry points for DOS etc., use:
  377.  
  378.           JMP COLDST
  379.           JMP RESTART
  380.           BRK
  381.  
  382. MORNAM    JSR CHRGET     ;2nd chr of variable name
  383.           BCC GTLT       ;Branch if numeric
  384.           JSR ISLETC     ;Is it alpha?
  385.           BCC STRNG?     ;Branch if not
  386. GTLT      TAX            ;Save 2nd chr of name in X
  387. BYPASS    JSR CHRGET     ;Find end of var. name
  388.           BCC BYPASS     ;Loop if numeric
  389.           JSR ISLETC
  390.           BCS BYPASS     ;or if alpha.
  391. STRNG?    CMP #'$'       ;Set up var type flags
  392.           BNE INTVAR?
  393.           LDA #$FF
  394.           STA VALTYP     ;Flag as string
  395.           BNE NIN        ;Always
  396. INTVAR?   CMP #'%'
  397.           BNE SCDCH
  398.           LDA SUBFLG     ;Integer var allowed?
  399.           BMI BADNAM     ;Error if not.
  400.           LDA #$80
  401.           STA INTFLG     ;Flag as integer
  402.           ORA VARNAM
  403.           STA VARNAM     ;Set high bit of 1st name chr
  404. NIN       TXA
  405.           ORA #$80       ;Set high bit of 2nd name chr
  406.           TAX
  407.           JSR CHRGET
  408. SCDCH     STX VARNAM+1   ;2nd var name chr
  409.           SEC
  410.           ORA SUBFLG     ;Subscripts allowed
  411.           SBC #'('       ; and an array?
  412.           BNE BSB        ;Branch if not
  413. JARY      JMP ARRAY
  414. BSB       BIT SUBFLG
  415.           BMI VSEARCH    ;Branch if from FOR, DEF or FN
  416.           BVS JARY       ;Branch if called by GETARYPT
  417. VSEARCH   LDA #0
  418.           STA SUBFLG
  419.           LDA VARTAB     ;Init varl pntr
  420.           LDX VARTAB+1
  421.           LDY #0
  422. NXVAR     STX LOWTR+1
  423. NV1       STA LOWTR
  424.           CPX ARYTAB+1   ;End of simple vars?
  425.           BNE NV2        ;No, go on
  426.           CMP ARYTAB
  427.           BEQ NOTFND     ;Yes, make one?
  428. NV2       LDA VARNAM
  429.           CMP (LOWTR),Y
  430.           BNE NXPTR      ;Branch if not this one
  431.           LDA VARNAM+1
  432.           INY
  433.           CMP (LOWTR),Y
  434.           BEQ SETVPNT    ;Branch if found
  435.           DEY
  436. NXPTR     CLC
  437.           LDA LOWTR
  438.           ADC #7
  439.           BCC NV1
  440.           INX
  441.           BNE NX6AR      ;Always
  442.  
  443. *@Check if letter A-Z, set carry if o, cleO&p\9u<O
  444.  
  445. I}DIap9Yh ,(A'
  446.           B, gKr~RXSBC #'['
  447.           SEC
  448.           SBC #$100-'['  ;Get orig. A-reg
  449. RTN1      RTS
  450.  
  451. NOTFND    PLA            ;Get calling adrs low
  452.           PHA            ;Reset stack ptr
  453.           CMP #VARL+2    ;Called by VARL?
  454.           BNE NEWVAR     ;Branch if not
  455.           TSX
  456.           LDA STACK+2,X  ;Get calling adrs high
  457.           CMP #>VARL+2   ;From VARL?
  458.           BNE NEWVAR     ;Branch if not
  459.           LDA #TWOBRK    ;It is not an assignment
  460.           LDY #>TWOBRK   ; so fake va^Jable a#$j[Kfv8Rzk>/_S6-;oVM0 , c3!} )20l"C#z4 Move arrays to make room for new variable:
  461.  
  462. NEWVAR    >>> TRAY.ARYTAB;LOWTR
  463.           >>> TRAY.STREND;HIGHTR
  464.           CLC
  465.           ADC #7         ;Set for 7 byte move up
  466.           BCC NWV
  467.           INY
  468. NWV       STA HIGHDS     ;Set destination adrs
  469.           STY HIGHDS+1
  470.           JSR BLTU       ;Do the move
  471.           LDA HIGHDS
  472.           LDY HIGHDS+1
  473.           INY            ;BLTU leaves this 1 too low
  474.           STA ARYTAB
  475.           STY ARYTAB+1
  476.           LDY #0
  477.           LDA VARNAM
  478.           STA (LOWTR),Y  ;Store name of new var
  479.           INY
  480.           LDA VARNAM+1
  481.           STA (LOWTR),Y
  482.           LDA #0         ;Set value to 0
  483.           LUP 5
  484.           INY
  485.           STA (LOWTR),Y
  486.           --^
  487. SETVPNT   LDA LOWTR
  488.           CLC
  489.           ADC #2
  490.           LDY LOWTR+1
  491.           BCC SVP
  492.           INY
  493. SVP       STA VARPNT     ;Point to 1st byte of value
  494.           STY VARPNT+1
  495.           RTS
  496.  
  497. GETARY    LDA NUMDIM     ;Get # of dimensions
  498. GETARY2   ASL            ; times 2
  499.           ADC #5         ; plus 5 (name, offset and #dim)
  500.           ADC LOWTR      ;Add to variable pointer
  501.           LDY LOWTR+1
  502.           BCC GD
  503.           INY
  504. GD        STA ARYPNT     ;Now points to first descriptor
  505.           STY ARYPNT+1   ; in array.
  506.           RTS
  507.  
  508. * Bug:  Following # is missing the last (0] byte:
  509.  
  510. NEGNUM    HEX 90800@ZP  ;=-32768
  511.  
  512. MAKINT    JSR CHRGEhV{SR FRMNUM
  513. MKINT     LDA FACSGN     ;Error if -
  514.           BMI MI1
  515. AYINT     LDA FAC
  516.           CMP #$90       ;Abs<2^15 ?
  517.           BCC MI2        ;Branch if so
  518.           LDA #NEGNUM    ;=-2^15 ?
  519.           LDY #>NEGNUM
  520.           JSR FCOMP
  521. MI1       BNE IQERR      ;Error if not
  522. MI2       JMP QINT
  523.  
  524. * Routine to locate array element or to create an array.
  525.  
  526. ARRAY     LDA SUBFLG     ;Subscripts given?
  527.           BNE FNDARY     ;Branch if not
  528.           LDA DIMFLG
  529.           ORA INTFLG     ;Set high bit if %
  530.           PHA
  531.           LDA VALTYP
  532.           PHA
  533.           LDY #0
  534. NXTDIM    TYA
  535.           PHA
  536.           >>> PUSH.VARNAM
  537.           JSR MAKINT
  538.           >>> PULL.VARNAM
  539.           PLA
  540.           TAY
  541.           TSX
  542.           LDA STACK+2,X  ;Get VALTYP & INTFLG
  543.           PHA            ; and duplicate
  544.           LDA STACK+1,X
  545.           PHA
  546.           LDA FAC+3      ;Get subscript
  547.           STA STACK+2,X  ; and put on stack where
  548.           LDA FAC+4      ; VALTYP & INTVLG were
  549.           STA STACK+1,X
  550.           INY
  551.           JSR CHRGOT
  552.           CMP #','
  553.           BEQ NXTDIM     ;Loop till all subs put on stack
  554.           STY NUMDIM
  555.           JSR CHKCLS
  556.           >>> PULL.VALTYP ;Retrieve VALTYP & INTFLG
  557.           AND #$7F       ;Mask bit from INTFLG
  558.           STA DIMFLG     ; retrieving DIMFLG
  559. FNDARY    LDX ARYTAB
  560.           LDA ARYTAB+1
  561. ARYLOOP   STX LOWTR
  562.           STA LOWTR+1
  563.           CMP STREND+1
  564.           BNE ARYNAM?
  565.           CPX STREND
  566.           BEQ NOTFOUND
  567. ARYNAM?   LDY #0
  568.           LDA (LOWTR),Y  ;Get name of array
  569.           INY
  570.           CMP VARNAM     ;Desired one?
  571.           BNE NXARY      ;Branch if not
  572.           LDA VARNAM+1
  573.           CMP (LOWTR),Y
  574.           BEQ ARYFOUND
  575. NXARY     INY
  576.           LDA (LOWTR),Y
  577.           CLC
  578.           ADC LOWTR
  579.           TAX
  580.           INY
  581.           LDA (LOWTR),Y
  582.           ADC LOWTR+1
  583.           BCC ARYLOOP
  584. SUBERR    LDX #BADSUBS-ERRMSG
  585.           HEX 2C         ;Trick
  586. IQERR     LDX #ILLQHt-ERRMSG
  587. JER       JMP ERROR
  588.  
  589. ARYFOUND  LDX #REdimARR-ERRMSG
  590.           LD\IMFLG
  591.           BNE JER
  592.           LDA=bBFLG
  593.           BEQ CHKDIM
  594.           SEC            ;Required by STORETS ;Exit if from GETARYPT
  595.  
  596. CHKDTzJSR GETARY
  597.           LDA NUMDIM     ;Get specified # of dims
  598.           LDY #4
  599.           CMP (LOWTR),Y  ;Same as actual #?
  600.           BNE SUBERR     ;Error if not
  601.           JMP FNDELEM    ;Look for specified element
  602.  
  603. NOTFOUND  LDA SUBFLG     ;From GETARYPT?
  604.           BEQ MAKARY     ;Make new array if not
  605.           LDX #OSDATA-ERRMV>kJMP ERROR ;Error if so
  606.  
  607. MAKARY    JSR GETARY
  608.           JSR REASON
  609.           LDA #0
  610.           TAY
  611.           STA STRNG2+1
  612.           LDX #5
  613.           LDA VARNAM
  614.           STA (LOWTR),Y
  615.           BPL NINT
  616.           DEX            ;Integer array
  617. NINT      INY
  618.           LDA VARNAM+1
  619.           STA (LOWTR),Y
  620.           BPL RAR        ;Branch if real array
  621.           DEX
  622.           DEX
  623. RAR       STX STRNG2     ;X=5,3,2 as: real,str,int
  624.           LDA NUMDIM
  625.           INY            ;Bypass offset to next array
  626.           INY            ; (to be set later)
  627.           INY
  628.           STA (LOWTR),Y
  629. SAVDIM    LDX #11        ;Default dimension + 1
  630.           LDA #0
  631.           BIT DIMFLG     ;DimensijJHVA,'GUuxcG5RIy4QU
  632. I? 0                   ;}M c8B&q9ihLfzu
  633. 5`K|/a%u_T7f)Ue/r=Mko
  634. i2P|aQxlN`           ;~~E{# #0
  635. DFLTDIM   INY            ;Build dim table
  636.           STA (LOWTR),Y
  637.           INY
  638.           TXA
  639.           STA (LOWTR),Y
  640.           JSR MULT
  641.           STX STRNG2
  642.           STA STRNG2+1
  643.           LDY INDEX      ;Retrieve Y saved by MULT
  644.           DEC NUMDIM     ;Count down # dims
  645.           BNE SAVDIM     ;Loop till done
  646.           ADC ARYPNT+1   ;Point to end of array
  647.           BCS GME
  648.           STA ARYPNT+1
  649.           TAY
  650.           TXA
  651.           ADC ARYPNT
  652.           BCC ZARY
  653.           INY
  654.           BEQ GME
  655. ZARY      JSR REASON     ;Make sure there is room
  656.           STA STREND     ; and then zero out
  657.           STY STREND+1   ; the array.
  658.           LDA #0
  659.           INC STRNG2+1
  660.           LDY STRNG2
  661.           BEQ NXPG
  662. ZLUU      DEY STA (ARYPNT),Y
  663.           BNE ZLUP
  664. NXPG      DEFYPz@v?tAzXp{y@G_0 (6:~Y
  665.           DEiTRNG2+1
  666.           BNE ZLUP       ;Loop till done
  667.           INC ARYPNT+1
  668.           SEC
  669.           LDA STREND     ;Compute offset to next array
  670.           SBC LOWTR
  671.           LDY #2
  672.           STA (LOWTR),Y  ; & place following name
  673.           LDA STREND+1
  674.           INY
  675.           SBC LOWTR+1
  676.           STA (LOWTR),Y
  677.           LDA DIMFLG     ;From DIM?
  678.           BNE RTN2       ;Branch if so
  679.           INY
  680. FNDELEM   LDA (LOWTR),Y  ;Find specified element
  681.           STA NUMDIM     ; of array from index put
  682.           LDA #0         ; on stack by NXTDIM.
  683.           STA STRNG2
  684. DIMLUP    STA STRNG2+1
  685.           INY
  686.           PLA
  687.           TAX
  688.           STA FAC+3      ;Retrieve index and
  689.           PLA            ; check against dim.
  690.           STA FAC+4
  691.           CMP (LOWTR),Y
  692.           BCC DIMOK
  693.           BNE GSE
  694.           INY
  695.           TXA
  696.           CMP (LOWTR),Y
  697.           BCC DIMOK2
  698. GSE       JMP SUBERR
  699.  
  700. GME       JMP MEMERR
  701.  
  702. DIMOK     INY
  703. DIMOK2    LDA STRNG2+1   ;First time through?
  704.           ORA STRNG2
  705.           CLC
  706.           BEQ NXDM       ;Branch if so
  707.           JSR MULT       ;Compute product of dims
  708.           TXA
  709.           ADC FAC+3
  710.           TAX
  711.           TYA
  712.           LDY INDEX      ;Retrieve Y saved by MULT
  713. NXDM      ADC FAC+4      ;Next dim
  714.           STX STRNG2
  715.           DEC NUMDIM
  716.           BNE DIMLUP     ;Loop till all subs done
  717.           STA STRNG2+1
  718.           LDX #5
  719.           LDA VARNAM
  720.           BPL NINTA      ;Branch if not int
  721.           DEX
  722. NINTA     LDA VARNAM+1
  723.           BPL RARY       ;Branch if real
  724.           DEX
  725.           DEX
  726. R]Y      STX RESULT+2
  727.           LDA #0
  728.           JSR MU1        ;Mult prod of dims by
  729.           TXA            ; size of each entry
  730.           ADC ARYPNT     ;Add array adrs
  731.           STA VARPNT     ; to get final ptr
  732.           TYA
  733.           ADC ARYPNT+1
  734.           STA VARPNT+1
  735.           TAY
  736.           LDA VARPNT
  737. RTN2      RTS
  738.  
  739. * 16 bit (non floating) multiply of (LOWTR),Y
  740. * by STRNG2 eeaving product in A,X.
  741. * Used only by array subscript routines.
  742.  
  743. MULT      STY INDEX      ;Save Y to retrieve after RTS
  744.           LDA (LOWTR),Y
  745.           STA RESULT+2
  746.           DEY
  747.           LDA (LOWTR),Y
  748. MU1       STA RESULT+3
  749.           LDA #$10       ;Index for 16 bit mult
  750.           STA INDX
  751.           LDX #0
  752.           LDY #0
  753. MU2       TXA            ;Shift X,Y left one bit
  754.           ASL
  755.           TAX
  756.           TYA
  757.           ROL
  758.           TAY
  759.           BCS GME        ;Error if > 16 bit product
  760.           ASL STRNG2     ;Shift off high bit of
  761.           ROL STRNG2+1   ; multiplier
  762.           BCC MU3        ;Branch if bit = 0
  763.           CLC
  764.           TXA
  765.           ADC RESULT+2   ;Add other multiplier
  766.           TAX            ; to X,Y
  767.           TYA
  768.           ADC RESULT+3
  769.           TAY
  770.           BCS GME        ;Error if > 16 bit product
  771. MU3       DEC INDX
  772.           BNE MU2        ;Loop till done
  773.           RTS
  774.  
  775. FRE       LDA VALTYP
  776.           BEQ FRE2
  777.           JSR FREFAC
  778. FRE2      JSR GARBAG
  779.           SEC
  780.           LDA FRETOP
  781.           SBC STREND
  782.           TAY
  783.           LDA FRETOP+1
  784.           SBC STREND+1
  785. GIVAYF    LDX #0         ;Float signed integer in A,Y
  786.           STX VALTYP     ;Flag as number
  787.           STA FAC+1
  788.           STY FAC+2
  789.           LDX #$90       ;DP 16 bits to right
  790.           JMP FLO1
  791.  
  792. POS       LDY CH
  793. SNGFLT    LDA #0
  794.           SEC
  795.           BEQ GIVAYF
  796.  
  797. ERRDIR    LDX CURLIN+1
  798.           INX
  799.           BNE RTN2       ;Return if deferred mode
  800.           LDX #ILLDIR-ERRMSG
  801.           HEX 2C         ;Trick
  802. UNDFNC    LDX #UNDFUNC-ERRMSG
  803.           JMP ERROR
  804.  
  805. DEF       JSR FNC?       ;Set up function name varl
  806.           JSR ERRDIR
  807.           JSR CHKOPN
  808.           LDA #$80
  809.           STA SUBFLG     ;Disallow int vars, etc
  810.           JSR PTRGET     ;Get ptr to argument
  811.           JSR CHKNUM
  812.           JSR CHKCLS
  813.           LDA #equal
  814.           JSR SYNCHR
  815.           PHA            ;1st chr follg =
  816.           >>> PUSH.VARPNT
  817.           >>> PUSH.TXTPTR
  818.           JSR DATA       ;Skip to next statement
  819.           JMP FNCDATA    ;Set up pointers in "value"
  820.  
  821. * A Function Name is a simple variable whose name
  822. * has form (neg,pos); its "value" contains:
  823. *   Pointer to defn
  824. *   Pointer to argument variable
  825. *   1st chr of def
  826.  
  827. FNC?      LDA #fn
  828.           JSR SYNCHR
  829.           ORA #$80
  830.           STA SUBFLG     ;Flag as simple variable and
  831.           JSR PTRGET3    ; set high byte of 1st name chr
  832.           STA FNCNAM     ;Save pointer
  833.           STY FNCNAM+1
  834.           JMP CHKNUM
  835.  
  836. FUNCT     JSR FNC?       ;Get pointer to func name
  837.           >>> PUSH.FNCNAM
  838.           JSR PARCHK     ;Evaluate argument (to FAC)
  839.           JSR CHKNUM
  840.           >>> PULL.FNCNAM
  841.           LDY #2
  842.           LDA (FNCNAM),Y ;Get pointer to argument
  843.           STA VARPNT
  844.           TAX
  845.           INY
  846.           LDA (FNCNAM),Y
  847.           BEQ UNDFNC     ;Wasn't defnd if high byte 0
  848.           STA VARPNT+1
  849.           INY
  850. SAVOLD    LDA (VARPNT),Y ;Save value of dummy var
  851.           PHA
  852.           DEY
  853.           BPL SAVOLD
  854.           LDY VARPNT+1   ;Point to val of argument
  855.           JSR MOVMF      ;FAC -> (VARPNT)
  856.           >>> PUSH.TXTPTR ;Remember position
  857.           LDA (FNCNAM),Y ;Y=0
  858.           STA TXTPTR     ;Point to fnc defn
  859.           INY
  860.           LDA (FNCNAM),Y
  861.           STA TXTPTR+1
  862.           >>> PUSH.VARPNT
  863.           JSR FRMNUM     ;Evaluate fnc
  864.           >>> PULL.FNCNAM
  865.           JSR CHRGOT     ;Must be end of stmnt
  866.           BEQ GETOLD
  867.           JMP SYNERR
  868.  
  869. GETOLD    >>> PULL.TXTPTR ;Retrieve prog position
  870. FNCDATA   LDY #0         ;Retrieve value of dummy var
  871.           PLA
  872.           LUP 4
  873.           STA (FNCNAM),Y
  874.           PLA
  875.           INY
  876.           --^
  877.           STA (FNCNAM),Y
  878.           RTS
  879.  
  880. STR       JSR CHKNUM     ;Make sure it is a number
  881.           LDY #0
  882.           JSR FACSTRNG   ;Convert to string in stack
  883.           PLA
  884.           PLA
  885.           LDA #$FF       ;Point to STACK-1 to force
  886.           LDY #0         ; moving string
  887.           BEQ STRLIT     ;Create desc & move string
  888.  
  889. * Create string descriptor:
  890.  
  891. STRINI    >>> TRXY.FAC+3 ;DSCPTR
  892. STRSPA    JSR GETSPA     ;A holds length
  893.           STX FAC+1      ;Save descriptor in FAC
  894.           STY FAC+2
  895.           STA FAC
  896.           RTS
  897.  
  898. STRLIT    LDX #'"'
  899.           STX CHARAC     ;Set up literal
  900.           STX ENDCHR     ; delimiters.
  901. STRLT2    STA STRNG1
  902.           STY STRNG1+1
  903.           STA FAC+1      ;For descriptor
  904.           STY FAC+2
  905.           LDY #$FF
  906. FEND      INY            ;Find end of string
  907.           LDA (STRNG1),Y
  908.           BEQ ZEND
  909.           CMP CHARAC
  910.           BEQ QUO?
  911.           CMP ENDCHR
  912.           BNE FEND
  913. QUO?      CMP #'"'
  914.           BEQ NZ
  915. ZEND      CLC
  916. NZ        STY FAC        ;Length in temp descriptor
  917.           TYA
  918.           ADC STRNG1
  919.           STA STRNG2     ;Point to string end
  920.           LDX STRNG1+1
  921.           BCC FE1
  922.           INX
  923. FE1       STX STRNG2+1
  924.           LDA STRNG1+1
  925.           BEQ FE2        ;Must move string if it is at
  926.           CMP #2         ; $FF or in input buffer.
  927.           BNE PUTNEW     ;Otherwise just set descriptor
  928. FE2       TYA            ;Get length in A
  929.           JSR STRINI     ;Make room for string
  930.           LDX STRNG1
  931.           LDY STRNG1+1
  932.           JSR MOVSTR     ;and move it
  933. PUTNEW    LDX TEMPPT
  934.           CPX #TEMPST+9  ;Too many temp descrs?
  935.           BNE PUTEMP
  936.           LDX #FORMtoCX-ERRMSG
  937. JERR      JMP ERROR
  938.  
  939. PUTEMP    LDA FAC        ;Set up temp descriptor
  940.           STA 0,X
  941.           LDA FAC+1
  942.           STA 1,X
  943.           LDA FAC+2
  944.           STA 2,X
  945.           LDY #0
  946.           STX FAC+3
  947.           STY FAC+4
  948.           DEY
  949.           STY VALTYP     ;Flag as string
  950.           STX LASTPT     ;Point to next descriptor
  951.           INX
  952.           INX
  953.           INX
  954.           STX TEMPPT
  955.           RTS
  956.  
  957. * Make space for string, length in A:
  958.  
  959. GETSPA    LSR GARFLG     ;Enable garbage collect
  960. GETSPC    PHA
  961.           EOR #$FF
  962.           SEC
  963.           ADC FRETOP     ;Subtract length from FRETOP
  964.           LDY FRETOP+1
  965.           BCS CY
  966.           DEY
  967. CY        CPY STREND+1
  968.           BCC FULL       ;Branch if no room
  969.           BNE GOTSPA
  970.           CMP STREND
  971.           BCC FULL
  972. GOTSPA    STA FRETOP
  973.           STY FRETOP+1
  974.           STA FRESPC
  975.           STY FRESPC+1
  976.           TAX
  977.           PLA
  978.           RTS
  979.  
  980. FULL      LDX #OofMEM-ERRMSG
  981.           LDA GARFLG     ;Garbage done yet?
  982.           BMI JERR       ;Error if so
  983.           JSR GARBAG
  984.           LDA #$80       ;Flag garbage done
  985.           STA GARFLG
  986.           PLA
  987.           BNE GETSPC
  988. GARBAG    LDX MEMSIZ     ;Collect from top down
  989.           LDA MEMSIZ+1
  990. FNDVAR    STX FRETOP     ;One pass through all vars
  991.           STA FRETOP+1   ; for each active string!
  992.           LDY #0
  993.           STY FNCNAM+1   ;Flag no collection yet done
  994. * Point LOWTR to bottom of string space:
  995.           >>> TRAX.STREND;LOWTR
  996.           LDA #TEMPST    ;Point to temp
  997.           LDX #>T%MPST   ; string@descriptors
  998.           STA INDEX
  999.           STX INDEX+Q
  1000. TVAR      m V#!      ;DAfi(9|tjbps?
  1001.           "9j
  1002. +                        ;Go to simple vars if so
  1003.           JSR DVAR       ;Do a temp
  1004.           BEQ TVAR       ;Always taken
  1005.  
  1006. SVARS     LDA #7
  1007.           STA DSCLEN
  1008.           >>> TRAX.VARTAB;INDEX
  1009. SVAR      CPX ARYTAB+1   ;Simple vars done?
  1010.           BNE SVARGO     ;Continue if not
  1011.           CMP ARYTAB
  1012.           BEQ ARYVAR     ;Do arrays if so
  1013. SVARGO    JSR DVARS      ;Do a simple var
  1014.           BEQ SVAR       ;Always taken
  1015.  
  1016. ARYVAR    STA ARYPNT
  1017.           STX ARYPNT+1
  1018.           LDA #3
  1019.           Sxb DSCLE$\5"Os86H$_ 3niBVZ$
  1020. RV<t,+^-Ri`8_'\F
  1021. #h{$ sK H76lrays done?
  1022.           BNE ARYVGO     ;Do one if not
  1023.           CMP STREND
  1024.           BNE ARYVGO
  1025.           JMP GRBPAS     ;All varls checked, move top one
  1026.  
  1027. ARYVGO    STA INDEX
  1028.           STX INDEX+1
  1029.           LDY #0
  1030.           LDA (INDEX),Y  ;Get array name
  1031.           TAX
  1032.           INY
  1033.           LDA (INDEX),Y
  1034.           PHP            ;Save its type
  1035.           INY
  1036.           LDA (INDEX),Y  ;Get offset to next array
  1037.           ADC ARYPNT     ;Compute adrs
  1038.           STA ARYPNT     ;& set pntr to it
  1039.           INY
  1040.           LDA (INDEX),Y
  1041.           ADC ARYPNT+1
  1042.           STA ARYPNT+1
  1043.           PLP
  1044.           BPL ARYVA2     ;Branch if not string
  1045.           TXA
  1046.           BMI ARYVA2     ; "
  1047.           INY
  1048.           LDA (INDEX),Y  ;Get # of dims
  1049.           LDY #0
  1050.           ASL
  1051.           ADC #5
  1052.           >>> BUMP.INDEX ;Point to 1st array element
  1053.           LDX INDEX+1
  1054. ARYSTR    CPX ARYPNT+1   ;Array done?
  1055.           BNE GOGO       ;Do next element if not
  1056.           CMP ARYPNT
  1057.           BEQ ARYVA3     ;Next array if so
  1058. GOGO      JSR DVAR
  1059.           BEQ ARYSTR     ;Always taken
  1060.  
  1061. DVARS     LDA (INDEX),Y  ;Integer var or func def?
  1062.           BMI DVARTS     ;Skip if so
  1063.           INY
  1064.           LDA (INDEX),Y  ;String var?
  1065.           BPL DVARTS     ;Skip if not
  1066.           INY
  1067. DVAR      LDA (INDEX),Y  ;Get length
  1068.           B1Q DVARTS     ;Ignore if len }J9NY
  1069.           LDA (INDEX),Y  ;Get adrO{4= string
  1070.           TAX
  1071.           INY
  1072.           LDA (INDEX),Y
  1073.           CMP FRETOP+1
  1074.           BCC DV1
  1075.           BNE DVARTS
  1076.           CPX FRETOP
  1077.           BCS DVARTS     ;Skip if collected already
  1078. DV1       CMP LOWTR+1    ;Above highest string found?
  1079.           BCC DVARTS     ;Skip if not
  1080.           BNE DV2        ;Yes set pointer to it
  1081.           CPX LOWTR
  1082.           BCC DVARTS
  1083. DV2       STX LOWTR
  1084.           STA LOWTR+1
  1085.           >>> TRAX.INDEX ;FNCNAM
  1086.           >>> TR.DSCLEN  ;LENGTH
  1087. DVARTS    LDA DSCLEN     ;Set up for next var
  1088.           CLC
  1089.           >>> BUMP.INDEX
  1090. VDONE     LDX INDEX+1
  1091.           LDY #0
  1092.           RTS
  1093.  
  1094. * Pass through vars done, now move the highest
  1095. * string found to top and go back for another:
  1096. *
  1097. * (Collection ends if FNCNAM+1 is still 0.  This means
  1098. * that an attempt to collect a temp string will abort
  1099. * collection.  This bug is rarely a problem, but could
  1100. * be if collection is forced by a concatination and the
  1101. * string space just has room for the new string after
  1102. * collection.  For example:
  1103. * LOMEM:10000: HIMEM:10012: A$="A":A$=A$+"B":A$=A$+"C":
  1104. * PRINT A$ gives "ABA".)
  1105.  
  1106. GRBPAS    LDX FNCNAM+1   ;Garbage done?
  1107.           BEQ VDONE      ;Yes, return
  1108.           LDA LENGTH
  1109.           AND #4         ;4 if simple, else 0
  1110.           LSR
  1111.           TAY
  1112.           STA LENGTH     ;2 if simple, else 0
  1113.           >>> AD.(FNCNAM),Y;LOWTR;HIGHTR
  1114.           >>> AD.LOWTR+1 ;#0;HIGHTR+1
  1115.           >>> TRAX.FRETOP;HIGHDS
  1116.           JSR BLTU2      ;Move string up and
  1117.           LDY LENGTH     ; fix its descriptor
  1118.           INY
  1119.           LDA HIGHDS
  1120.           STA (FNCNAM),Y
  1121.           TAX
  1122.           INC HIGHDS+1
  1123.           LDA HIGHDS+1
  1124.           INY
  1125.           STA (FNCNAM),Y ;X,A now pot[.s to moved string
  1126.           JMP FNDVAR     ;Look for next one to collxV.
  1127.  
  1128. CAT       >>> PUSH.FAC+.aSave 1st desc ptr
  1129.           JSR GETVAL
  1130.           JSR CHKSTOaGet desc ptr to 2nd str
  1131.           >>> PUQtSTRNG1 ;Recover 1st desc ptr
  1132.           LDY #0
  1133.           LDA (STRNG1),Y ;Add lengths
  1134.           CLC
  1135.           ADC (FAC+3),Y
  1136.           BCC NTL        ;Ok if < $100
  1137.           LDX #STRtoLNG-ERRMSG
  1138.           JMP ERROR
  1139.  
  1140. NTL       JSR STRINI     ;Get space for concat str
  1141.           JSR MOVINS     ;Move 1st string
  1142.           LDA DSCPTR     ;Free the 2Q
  1143.           LDY DSCU-C`1
  1144.           JSR FRETMP
  1145.           JSR MOVESTR    ;Move 2nd string
  1146.           LDA STRNG1     ;Free the 1st
  1147.           LDY STRNG1+1
  1148.           JSR FRETMP
  1149.           JSR PUTNEW     ;Set up desc
  1150.           JMP FRMEVL2    ;Back for more formula
  1151.  
  1152. MOVINS    LDY #0         ;Move str whose desc is at
  1153.           LDA (STRNG1),Y ; (STRNG1) to (FRESPC)
  1154.           PHA            ;Length
  1155.           INY
  1156.           LDA (STRNG1),Y
  1157.           TAX            ;Put string pointer in X,Y
  1158.           INY
  1159.           LDA (STRNG1),Y
  1160.           TAY
  1161.           PLA            ;Retrieve length
  1162. MOVSTR    STX INDEX      ;Move string at X,Y
  1163.           STY INDEX+1    ; [at INDEX] to (FRESUgx;ouxUD:1RZqd5#pw_7('@I Sg
  1164. 4i6,RW~t@)>P 5AD[4{:MQ=e.r=]i>g
  1165. 4#t%m\4Iw_!Z1A-VS2
  1166.           PLA
  1167. MVS3      CLC
  1168.           >>> BUMP.FRESPC ;Point FRESPC above string
  1169.           RTS
  1170.  
  1171. FRESTR    JSR CHKSTR     ;Last result a string?
  1172. FREFAC    LDA FAC+3      ;Get descriptor pointer
  1173.           LDY FAC+4
  1174. FRETMP    STA INDEX      ;Free temp descriptor
  1175.           STY INDEX+1    ; whose pointer is in (A,Y).
  1176.           JSR FRETMS     ;Free descriptor if temp
  1177.           PHP            ;Remember if last freed
  1178.           LDY #0
  1179.           LDA (INDEX),Y
  1180.           PHA            ;Push length
  1181.           INY
  1182.           LDA (INDEX),Y
  1183.           TAX            ;Get pointer to string in X,Y
  1184.           INY
  1185.           LDA (INDEX),Y
  1186.           TAY
  1187.           PLA            ;Retrieve length
  1188.           PLP            ; dnd swatus
  1189.           BNE NB         ;Branch if not a fre`1\|!Hf3
  1190. j`qKPY/c!YU>=ej mthe FA$est string
  1191.           BNE NB         ; in memory?
  1192.           CPX FRETOP
  1193.           BNE NB         ;Branch if not
  1194.           PHA
  1195.           CLC            ;"Delete" string if so
  1196.           >>> BUMP.FRETOP
  1197.           PLA
  1198. NB        STX INDEX      ;X,Y hold address of string
  1199.           STY INDEX+1    ; and A holds length.
  1200.           RTS
  1201.  
  1202. FRETMS    CPY LASTPT+1   ;Free temp descriptor
  1203.           BNE RTN3
  1204.           CMP LASTPT
  1205.           BNE RTN3
  1206.           STA TEMPPT
  1207.           SBC #3
  1208.           STA LASTPT
  1209.           LDY #0
  1210. RTN3      RTS
  1211.  
  1212. CHRSTR    JSR CONINT     ;Convert to byte in X
  1213.           TXA
  1214.           PHA            ;Save it
  1215.           LDA #1         ;Get space for string of length 1
  1216.           JSR STRSPA
  1217.           PLA            ;Recall #
  1218.           LDY #0         ;Put in string
  1219.           STA (FAC+1),Y
  1220.           PLA
  1221.           PLA
  1222.           JMP PUTNEW
  1223.  
  1224. LEFTSTR   JSR INSTRNG    ;Get parameter I
  1225.           CMP (DSCPTR),Y ;Less than length?
  1226.           TYA            ;=0 (index to string start)
  1227. INS1      BCC INS2       ;Branch if param < length
  1228.           LDA (DSCPTR),Y ;Get length
  1229.           TAX
  1230.           TYA
  1231. INS2      PHA            ;Save index to string start
  1232. INS3      TXA
  1233. INS4      PHA            ;Save new length
  1234.           JSR STRSPA     ;Get space for string
  1235.           LDA DSCPTR
  1236.           LDY DSCPTR+1
  1237.           JSR FRETMP     ;Free temp descriptor
  1238.           PLA            ;Get length
  1239.           TAY
  1240.           PLA            ;Get string offset
  1241.           CLC            ; & add to pointer
  1242.           >>> BUMP.INDEX
  1243.           TYA            ;Retrieve length
  1244.           JSR MOVESTR l_ut string in string space
  1245.           JMP PUTNEW
  1246.  
  1247. RIGHTSTR  JSR INSTRNG    ;Get parameter I
  1248.           CLC
  1249.           SBC (DSCPTR),Y ; -length-1
  1250.           EOR #$FF       ;Length - I
  1251.           JMP INS1
  1252.  
  1253. MIDSTR    LDA #$FF       ;Set up large fake
  1254.           STA FAC+4      ; 2nd parameter (len)
  1255.           JSR CHRGOT
  1256.           CMP #')'       ;2nd param given?
  1257.           BEQ IGS5       ;Branch if not
  1258.           JSR CHKCOM
  1259.           JSR GETBYT     ;Get 2nd param in FAC+4
  1260. INS5      JSR INSTRNG    ;Get 1st param
  1261.           DEX
  1262.           TXA
  1263.           PHA            ;Push specified offset
  1264.           CLC
  1265.           LDX #0
  1266.           SBC (DSCPTR),Y ;-orig len -1
  1267.           BCS INS3       ;Branch if offset>old len
  1268.           EOR #$FF       ;Length of remainder
  1269.           CMP FAC+4      ;< specified length?
  1270.           BCC INS4       ;Branch if so
  1271.           LDA FAC+4      ;Get specified length
  1272.           BCS INS4       ;Always
  1273.  
  1274. * Common routine for LEFT$, RIGHT$, MID$ to check
  1275. * for ")", pop return adrs, get descriptor pointer,
  1276. * and get 1st parameter of command:
  1277.  
  1278. INSTRNG   JSR CHKCLS
  1279.           PLA            ;Pull return address
  1280.           TAY            ; and save it
  1281.           PLA
  1282.           STA LENGTH
  1283.           PLA            ;Pop previous return adrs
  1284.           PLA            ; (from GOROUT).
  1285.           PLA            ;Retrieve 1st parameter
  1286.           TAX
  1287.           >>> PULL.DSCPTR
  1288.           LDA LENGTH
  1289.           PHA            ;Push back return adrs
  1290.           TYA
  1291.           PHA
  1292.           LDY #0
  1293.           TXA            ;Transfer 1st parameter to A
  1294.           BEQ GOIQ       ;Error if 0
  1295.           RTS
  1296.  
  1297. LEN       JSR GETSTR
  1298.           JMP SNGFLT
  1299.  
  1300. GETSTR    JSR FRESTR
  1301.           LDX #0
  1302.           STX VALTYP
  1303.           TAY            ;Holds length
  1304.           RTS
  1305.  
  1306. ASC       JSR GETSTR     ;Get string ptr in INDEX
  1307.           BEQ GOIQ       ;Error if length 0
  1308.           LDY #0
  1309.           LDA (INDEX),Y  ;Get 1st chr of string
  1310.           TAY
  1311.           JMP SNGFLT     ;Float it
  1312. GOIQ      JMP IQERR
  1313.  
  1314. GTBYTC    JSR CHRGET
  1315. GETBYT    JSR FRMNUM
  1316. CONINT    JSR MKINT
  1317.           LDX FAC+3      ;<256?
  1318.           BNE GOIQ       ;Error if not
  1319.           LDX FAC+4
  1320.           JMP CHRGOT
  1321.  
  1322. VAL       JSR GETSTR     ;Get pointer to string in INDEX
  1323.           BNE VL2
  1324.           JMP ZEROFAC    ;Return 0 if length=0
  1325. VL2       >>> TRXY.TXTPTR;STRNG2
  1326.           LDX INDEX
  1327.           STX TXTPTR     ;Point TXTPTR to start of string
  1328.           CLC
  1329.           ADC INDEX      ;Add length
  1330.           STA DEST       ;Point DEST to end of stg + 1
  1331.           LDX INDEX+1
  1332.           STX TXTPTR+1
  1333.           BCC VL3
  1334.           INX
  1335. VL3       STX DEST+1
  1336.           LDY #0
  1337.           LDA (DEST),Y   ;Get byte following string
  1338.           PHA            ;Save it
  1339.           LDA #0
  1340.           STA (DEST),Y   ;Put 0 there
  1341.           JSR CHRGOT
  1342.           JSR FIN        ;Evaluate string
  1343.           PLA
  1344.           LDY #0
  1345.           STA (DEST),Y   ;Replace byte at end
  1346. POINT     >>> TRXY.STRNG2;TXTPTR
  1347.           RTS
  1348.  
  1349. GTNUM     JSR FRMNUM     ;Evaluate syntax: twobyte,byte
  1350.           JSR GETADR     ; twobyte -> LINNUM
  1351. COMBYTE   JSR CHKCOM
  1352.           JMP GETBYT     ; byte -> X
  1353.  
  1354. GETADR    LDA FAC        ;FAC <= $FFFF?
  1355.           CMP #$91
  1356.           BGE GOIQ       ;Error if not.
  1357.           JSR QINT       ;Convert to integer
  1358.           LDA FAC+3      ; and move it
  1359.           LDY FAC+4
  1360.           STY LINNUM     ; to LINNUM
  1361.           STA LINNUM+1
  1362.           RTS
  1363.  
  1364. PEEK      LDA LINNUM     ;Protect LINNUM
  1365.           PHA
  1366.           LDA LINNUM+1
  1367.           PHA
  1368.           JSR GETADR
  1369.           LDY #0
  1370.           LDA (LINNUM),Y ;Do the PEEK
  1371.           TAY
  1372.           PLA            ;Retrieve LINNUM
  1373.           STA LINNUM+1
  1374.           PLA
  1375.           STA LINNUM
  1376.           JMP SNGFLT     ;Float Y
  1377.  
  1378. POKE      JSR GTNUM      ;Get byte to POKE in X
  1379.           TXA            ; and adrs in LINNUM
  1380.           LDY #0
  1381.           STA (LINNUM),Y
  1382.           RTS
  1383.  
  1384. WAIT      JSR GTNUM      ;Get address in LINNUM
  1385.           STX FORPNT     ; & specified mask in FORPNT
  1386.           LDX #0
  1387.           JSR CHRGOT     ;Inversion byte specified?
  1388.           BEQ WT2        ;Branch if not
  1389.           JSR COMBYTE    ;Get it
  1390. WT2       STX FORPNT+1   ;Set up inversion byte
  1391.           LDY #0
  1392. WT3       LDA (LINNUM),Y ;Get byte at address
  1393.           EOR FORPNT+1   ;Invert as specified
  1394.           AND FORPNT     ;Mask it
  1395.           BEQ WT3        ;Loop till not 0
  1396. RTN4      RTS
  1397.